import java.awt.*;
import java.awt.event.*;
import java.util.*;
class MouseData
{
	boolean _pressed;
	int _x1;
	int _x2;
	int _y1;
	int _y2;
	MouseData()
	{
		_pressed=false;
		_x1=_x2=_y1=_y2=0;
	}
	void sort()
	{
		int q=0;
		if(_x1>_x2)
	       	{
			q=_x2;
			_x2=_x1;
			_x1=q;
		}
		if(_y1>_y2)
		{
			q=_y2;
			_y2=_y1;
			_y1=q;
		}
	}
}
class Plot extends Canvas implements MouseListener, MouseMotionListener
{
	float _xmin;
	float _xmax;
	float _ymin;
	float _ymax;
	int _xsize;
	int _ysize;
	int _xmargin;
	int _ymargin;
	MouseData _seldata;
	LinkedList<Point> _points;
	void drawPoint(Graphics g,Point p)
	{
		int xc=_xmargin+(int)Math.floor((p._xc-_xmin)/(_xmax-_xmin)*_xsize);
		int yc=(int)Math.floor(_ysize-(p._yc-_ymin)/(_ymax-_ymin)*_ysize);
		g.fillOval(xc-2,yc-2,4,4);
	}
	void drawAxis(Graphics g)
	{
		g.drawLine(_xmargin,_ysize,_xmargin+_xsize,_ysize);
		g.drawLine(_xmargin,0,_xmargin,_ysize);
		for(int i=0;i<_xsize/100;i++)
		{
			g.drawLine(_xmargin+100*i,_ysize+5,_xmargin+100*i,_ysize-5);
			g.drawString(Float.toString((_xmax-_xmin)*i*100/_xsize+_xmin),_xmargin+100*i-20,_ymargin+_ysize-15);
		}
		for(int i=0;i<_ysize/100;i++)
		{
			g.drawLine(_xmargin-5,_ysize-100*i,_xmargin+5,_ysize-100*i);
			g.drawString(Float.toString((_ymax-_ymin)*i*100/_ysize+_ymin),_xmargin-30,_ysize-100*i+5);
		}
	}
	void drawSelection(Graphics g)
	{
		g.setColor(Color.black);
		int x,y;
		if(_seldata._pressed)
		{
			x=Math.min(_seldata._x1,_seldata._x2);
			y=Math.min(_seldata._y1,_seldata._y2);
			g.drawRect(x,y,Math.abs(_seldata._x2-_seldata._x1),Math.abs(_seldata._y2-_seldata._y1));
		}
	}
	Plot(int xs,int ys,float xm,float xmx,float ym,float ymx,int xmar,int ymar)
	{
		_xsize=xs;
		_ysize=ys;
		_xmin=xm;
		_xmax=xmx;
		_ymin=ym;
		_ymax=ymx;
		_xmargin=xmar;
		_ymargin=ymar;
		_points=new LinkedList<Point>();
		_seldata=new MouseData();
		addMouseListener(this);
		addMouseMotionListener(this);
	}
	public void paint(Graphics g)
	{
		drawAxis(g);
		if(_points!=null)
		{
			ListIterator<Point> i=_points.listIterator();
			while(i.hasNext())
			{
				drawPoint(g,i.next());
			}
		}
		drawSelection(g);
	}
	void plot(LinkedList<Point> pnt)
	{
		_points=pnt;
	}
	void addPoint(Point p)
	{
		if(_points==null) _points=new LinkedList<Point>();
		_points.addLast(p);
	}
	void setXRange(float min,float max)
	{
		_xmin=min;
		_xmax=max;
	}
	void setYRange(float min,float max)
	{
		_ymin=min;
		_ymax=max;
	}
	void setRange(float xm,float xmx,float ym,float ymx)
	{
		setXRange(xm,xmx);
		setYRange(ym,ymx);
	}
	public void mousePressed(MouseEvent me)
	{
		_seldata._x1=me.getX();
		_seldata._y1=me.getY();
		_seldata._pressed=true;
	}
	public void mouseReleased(MouseEvent me)
	{
		float x1,x2,y1,y2;
		if(_seldata._pressed)
		{
			_seldata.sort();
			_seldata._x1-=_xmargin;
			_seldata._x2-=_xmargin;
			_seldata._y1=_ysize-_seldata._y1;
			_seldata._y2=_ysize-_seldata._y2;
			x1=_xmin+((_xmax-_xmin)*_seldata._x1)/_xsize;
			x2=_xmin+((_xmax-_xmin)*_seldata._x2)/_xsize;
			y1=_ymin+((_ymax-_ymin)*_seldata._y2)/_ysize;
			y2=_ymin+((_ymax-_ymin)*_seldata._y1)/_ysize;
			setRange(x1,x2,y1,y2);
			_seldata._pressed=false;
		}
		repaint();
	}
	public void mouseClicked(MouseEvent me)
	{}
	public void mouseEntered(MouseEvent me)
	{}
	public void mouseExited(MouseEvent me)
	{}
	public void mouseMoved(MouseEvent me)
	{}
	public void mouseDragged(MouseEvent me)
	{
		_seldata._x2=me.getX();
		_seldata._y2=me.getY();
		repaint();
	}
}
